<?php
namespace app\shop\controller;

use app\common\controller\Shop;
use app\common\model\Business\Address;
use app\common\model\Business\Commission;
use app\common\model\Business\Record;
use app\common\model\Coupon\Coupon;
use app\common\model\Coupon\Receive;
use app\common\model\Depot\Back\Back;
use app\common\model\Depot\Back\Product as BackProduct;
use app\common\model\Depot\Storage\Product as StorageProduct;
use app\common\model\Depot\Storage\Storage;
use app\common\model\Order\Order as OrderOrder;
use app\common\model\Order\Product as OrderProduct;
use app\common\model\Pay;
use app\common\model\Product\Cart;
use app\common\model\Product\Product;
use think\Request;
use Exception;
use fast\Http;
use fast\Random;
use think\config\driver\Json;
use think\Db;
use think\exception\ValidateException;
use think\exception\PDOException;
use think\File;

use function PHPSTORM_META\map;

class Order extends Shop
{
    protected $model = null;
    public function __construct(Request $request)
    {
        $this->noLogin = [];
        parent::__construct($request);
        $this->model = new OrderOrder();
    }
    public function index()
    {
        if($this->request->isGet())
        {
            $page = $this->request->get('page',1,'trim');
            $pageSize = $this->request->get('pageSize',6,'trim');
            $status = $this->request->get('status','','trim');
            $where = ['product.busid'=>$this->business['id']];
            if($status){
                $where['product.status'] = $status;
            }
            $orderProductList = OrderProduct::with(['order','product_product'])->where($where)->order('createtime','desc')->paginate($pageSize,$page);
            foreach ($orderProductList as $key => $orderProduct) {
                //订单金额
                $coupon = Coupon::where('id',$orderProduct->order['couponid'])->find();
                $rate = $coupon?$coupon['rate']:1;
                $orderProduct['orderTotal'] = round($rate*$orderProduct['total'],2);
                // 这里的 $item 代表每一条记录的数组
                // 进行你需要的修改操作
                // 保存修改后的值回到 Paginator 对象中
                $orderProductList->offsetSet($key, $orderProduct);
            }
            return $orderProductList;
        }else if($this->request->isPost())
        {
            $busid = $this->business['id'];
            $addressModel = new Address();
            $receiveModel = new Receive();
            $cartModel = new Cart();
            $payModel = new Pay();
            $where = ['busid'=>$busid];
            //地址
            $businessaddrid = $this->request->post('businessaddrid');
            $address = $addressModel->where($where)->where('id',$businessaddrid)->find();
            if(!$address)$this->error('地址不存在');
            //优惠券
            $couponid = $this->request->post('couponid',0);
            $rate = 1;
            $receive = null;
            if($couponid!=0){
                $where_receive = ['cid'=>$couponid,'receive.status'=>'1','coupon.status'=>'1'];
                $receive = $receiveModel->with(['coupon'])->where($where)->where($where_receive)->find();
                if(!$receive)$this->error('优惠券不存在');
                $rate = $receive->coupon['rate'];
            }
            //订单金额
            $cart = $cartModel->with(['product'])->where($where)->where('cart.status','1')->select();
            if(!$cart->count())$this->error('购买的商品为空');
            $amount = round(array_sum($cart->column('total'))*$rate,2);
            //支付方式
            $type = $this->request->post('pay','money','trim');
            //订单留言
            $remark = $this->request->post('remark','','trim');
            //订单号
            $code = 'SP'.date('YmdHis',time()).random_int(1000000,9999999);
            
            $result = null;
            $orderStatus = '0';
            $order = null;
            $pay = null;
            Db::startTrans();
            try {
                if($type=='money')
                {
                    //business减余额
                    if($this->business['money']<$amount)throw new Exception('余额不足');
                    $this->business['money'] -= $amount;
                    $this->business->isUpdate()->save();
                    $orderStatus = '1';
                }
                //order添加订单
                $params = [
                    'code'=>$code,
                    'busid'=>$busid,
                    'businessaddrid'=>$businessaddrid,
                    'amount'=>$amount,
                    'remark'=>$remark,
                    'status'=>$orderStatus,
                    'pay'=>$type
                ];
                if($receive){
                    $params['couponid'] = $couponid;
                }
                $order = $this->model->allowField(true)->create($params);
                $payList = $this->model->getPaycodeList();
                if($type!='money'){
                    $params = [
                        'code'=>$code,
                        'name'=>'商品购买',
                        'third'=>json_encode(['busid'=>$this->business['id']]),
                        'type'=>$type,
                        'total'=>$amount,
                        'price'=>$amount,
                        'cashier'=>'1',
                        'status'=>$orderStatus,
                    ];
                    $params['qrcode'] = $payList[$type];
                    $pay = $payModel->create($params);
                }
                if($orderStatus=='1')
                {
                    $this->payed($order,$cart,$receive);
                }
                Db::commit();
            } catch (ValidateException|PDOException|Exception $e) {
                Db::rollback();
                $this->error($e->getMessage());
            }
            if (false === $result) {
                $this->error('下单失败');
            }
            if($orderStatus=='1')
            {
                $this->success('下单成功');
            }else{
                $this->result($pay['id'],-1,"未支付");
            }
        }
    }
    private function payed($order,$cart=null,$receive=null)
    {
        $cartModel = new Cart();
        $commissionModel = new Commission();
        $recordModel = new Record();
        $productModel = new Product();
        $orderProductModel = new OrderProduct();
        $receiveModel = new Receive();
        if(!$cart){
            $cart = $cartModel->with(['product'])->where('busid',$this->business['id'])->where('cart.status','1')->select();
        }

        //coupon修改优惠券状态
        $rate = 1;
        if(isset($order['couponid'])&&$order['couponid']){
            if(!$receive){
                $where_receive = ['cid'=>$order['couponid'],'receive.status'=>'1','coupon.status'=>'1'];
                $receive = $receiveModel->with(['coupon'])->where('busid',$this->business['id'])->where($where_receive)->find();
            }
            $receive['status'] = '0';
            $rate = $receive['coupon']['rate'];
            $receive->allowField(true)->isUpdate(true)->save();
        }

        //orderProduct添加订单商品
        $params = [];
        foreach($cart as $c)
        {
            $params[] = [
                'orderid'=>$order['id'],
                'busid'=>$this->business['id'],
                'proid'=>$c['proid'],
                'pronum'=>$c['nums'],
                'price'=>$c['price']*$rate,
                'total'=>$c['total']*$rate,
                'attrs'=>$c['attrs'],
                'status'=>'0',
                'code'=>'SP'.date('YmdHis',time()).Random::numeric(7),
            ];
        }
        $orderProductModel->isUpdate(false)->saveAll($params);
        
        //product减库存
        $productList = [];
        foreach($cart as $c)
        {
            if(!isset($productList[$c['proid']])){
                $productList[$c['proid']] = $c->product['stock'];
            }
            $productList[$c['proid']] -= $c['nums'];
            if($productList[$c['proid']]<0)throw new Exception('库存不足');
        }
        $params = [];
        foreach(array_keys($productList) as $pk)
        {
            $params[] = ['id'=>$pk,'stock'=>$productList[$pk]];
        }
        $result = $productModel->isUpdate()->saveAll($params);

        if($this->business['parentid']){
            //commission添加佣金
            $params = [
                'orderid'=>$order['id'],
                'busid'=>$this->business['id'],
                'parentid'=>$this->business['parentid'],
                'amount'=>$order['amount']*config('site.amountRate'),
                'type'=>'product',
                'status'=>'0',
            ];
            $commissionModel->allowField(true)->save($params);
        }

        //record添加消费记录
        foreach($cart as $c)
        {
            $params = [
                'total'=>-$c['total']*$rate,
                'content'=>'购买商品：【'.$c->product['name'].'】'.join('|',$c->prop_list).'花费了 ￥'.$c['total']*$rate.' 元',
                'busid'=>$this->business['id']
            ];
        }
        $recordModel->allowField(true)->save($params);

        //cart删除购物车
        $cartidList = [];
        foreach($cart as $c)
        {
            $cartidList[] = $c['id'];
        }
        $cartModel->where('id','in',$cartidList)->delete();
    }
    public function pay()
    {
        $busid = $this->business['id'];
        $payid = $this->request->param('payid');
        $pay = Pay::where(['id'=>$payid])->find();
        if(!$pay||(json_decode($pay['third'])->busid!=$busid))$this->error('订单不存在');
        if($this->request->isGet())
        {
            if($pay['status']=='0')
            {
                $this->success('未支付',null,$pay);
            }else
            {
                $this->result(null,-1,'已支付');
            }
        }else if($this->request->isPut())
        {
            $money = $this->request->post('money');
            if($money==$pay['price'])
            {
                $result = null;
                Db::startTrans();
                try {
                    //pay 修改已支付
                    $pay['status'] = '1';
                    $pay->isUpdate()->save();
                    //order 订单已支付
                    $order = $this->model->where('code',$pay['code'])->find();
                    $order['status'] = '1';
                    $result = $order->isUpdate()->save();
                    $this->payed($order);
                    Db::commit();
                } catch (ValidateException|PDOException|Exception $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                }
                if (false === $result) {
                    $this->error('下单失败');
                }
                $this->success('支付成功');
            }else{
                $this->result(null,-1,'支付失败');
            }
        }
    }
    public function check()
    {
        $busid = $this->business['id'];
        $payid = $this->request->param('payid');
        $pay = Pay::where(['id'=>$payid])->find();
        if(!$pay||json_decode($pay['third'])->busid!=$busid)$this->error('订单不存在');
        if($this->request->isGet())
        {
            if($pay['status']=='0')
            {
                $this->result(null,-1,'未支付');
            }else if($pay['status']=='2')
            {
                $this->error('支付已过期');
            }else
            {
                $this->success('已支付');
            }
        }else{
            $pay['status'] = '2';
            $result = $pay->isUpdate()->save();
            $result!==false?$this->success():$this->error();
        }
        
        
    }
    public function info()
    {
        if($this->request->isGet())
        {
            $id = $this->request->get('id',0,'trim');
            $where = ['order.busid'=>$this->business['id'],'product.id'=>$id];
            $orderProduct =  OrderProduct::with(['order','product_product'])->where($where)->find();
            //订单金额
            $coupon = Coupon::where('id',$orderProduct->order['couponid'])->find();
            $rate = $coupon?$coupon['rate']:1;
            $orderProduct['orderTotal'] = round($rate*$orderProduct['total'],2);
            //地址
            $businessaddrid = $orderProduct->order['businessaddrid'];
            $address = Address::withTrashed()->where('id',$businessaddrid)->find();
            $orderProduct['address'] = $address;
            if($orderProduct){
                $this->success('',null,$orderProduct);
            }else{
                $this->error();
            }
        }
    }
    public function refund()
    {
        if($this->request->isPut())
        {
            $orderProductId = $this->request->get('orderProductId');
            $refundreason = $this->request->post('refundreason','','trim');
            $orderProduct = OrderProduct::with('order')->where('product.id',$orderProductId)->find();
            if(!$orderProduct)$this->error('订单不存在');
            $result = false;
            Db::startTrans();
            try {
                if($orderProduct['status']=='0')
                {
                    $this->business['money'] += $orderProduct['total'];
                    $this->business->isUpdate()->save();
                    $orderProduct['refundreason'] = $refundreason;
                    $orderProduct['status'] = '-1';
                }else if($orderProduct['status']>='2')
                {
                    $orderProduct['refundreason'] = $refundreason;
                    $orderProduct['status'] = '-2';
                    //storage 添加入库信息
                    $storageModel = new Storage();
                    $params = [
                        'code'=>'SU'.date('YmdHis',time()).Random::numeric(7),
                        'type'=>'2',
                        'amount'=>$orderProduct['total'],
                        'status'=>'0',
                    ];
                    $storage = $storageModel->allowField(true)->create($params);
                    //StorageProduct 添加入库商品
                    $storageProductModel = new StorageProduct();
                    $params = [
                        'storageid'=>$storage['id'],
                        'proid'=>$orderProduct['proid'],
                        'nums'=>$orderProduct['pronum'],
                        'price'=>$orderProduct['price'],
                        'total'=>$orderProduct['total'],
                    ];
                    $storageProductModel->allowField(true)->create($params);
                    //back 添加退货信息
                    $backModel = new Back();
                    $params = [
                        'code'=>'BK'.date('YmdHis',time()).Random::numeric(7),
                        'ordercode'=>$orderProduct['code'],
                        'busid'=>$this->business['id'],
                        'amount'=>$orderProduct['total'],
                        'status'=>'0',
                        'storageid'=>$storage['id'],
                    ];
                    $back = $backModel->allowField(true)->create($params);
                    //BackProduct 添加退货商品
                    $backProductModel = new BackProduct();
                    $params = [
                        'backid'=>$back['id'],
                        'proid'=>$orderProduct['proid'],
                        'nums'=>$orderProduct['pronum'],
                        'price'=>$orderProduct['price'],
                        'total'=>$orderProduct['total'],
                    ];
                    $result = $backProductModel->allowField(true)->create($params);
                }else{
                    $this->error($orderProduct['status_text'].'无法退款');
                }
                $result = $orderProduct->isUpdate()->save();
                Db::commit();
            } catch (ValidateException|PDOException|Exception $e) {
                Db::rollback();
                $this->error($e->getMessage());
            }
            if($result===false)$this->error('申请失败，请重新申请');
            $this->success('申请中，请等待审核');
        }else if($this->request->isGet())
        {
            $backModel = new Back();
            $back = $backModel->where('ordercode',$this->request->get('ordercode','','trim'))->find();
            $back&&$back['expresscode']?$this->success('',null,$back):$this->error('查无退货信息');
        }
    }
    public function upload()
    {
        $status = ['code'=>1,'msg'=>''];
        if(!isset($_FILES['thumbs']))return $status;
        $thumbs = $_FILES['thumbs'];
        $thumbList = [];
        foreach(range(0,count($thumbs['name'])-1) as $index)
        {
            $thumbList[$index]['name'] = $thumbs['name'][$index];
            $thumbList[$index]['type'] = $thumbs['type'][$index];
            $thumbList[$index]['tmp_name'] = $thumbs['tmp_name'][$index];
            $thumbList[$index]['error'] = $thumbs['error'][$index];
            $thumbList[$index]['size'] = $thumbs['size'][$index];
        }
        $status = ['code'=>0,'msg'=>''];
        $fileList = [];
        foreach($thumbList as $thumb)
        {
            $file = (new File($thumb['tmp_name']))->setUploadInfo($thumb);
            $result = $file->validate(['ext'=>'jpg,png,gif'])->move(ROOT_PATH . 'public' . '/' . 'uploads');
            if($result){
                $fileList[] = '/' . 'uploads' . '/' . $result->getSaveName();
            }
        }
        
        if(count($fileList)==count($thumbList))
        {
            $status['msg'] = join('|',$fileList);
        }else{
            foreach($fileList as $file)
            {
                @unlink(ROOT_PATH . 'public' . '/' . 'uploads' . $file);
            }
            $status['code'] = 0;
        }
        return $status;
    }
    public function comment()
    {
        $this->request->filter(['strip_tags', 'trim']);
        if($this->request->isPost())
        {
            $id = $this->request->post('id',0);
            $orderProduct = OrderProduct::where(['id'=>$id,'busid'=>$this->business['id']])->find();
            if(!$orderProduct)$this->error('找不到商品订单');
            if($orderProduct['status']!='2')$this->error('商品订单无法评论');
            $comment = $this->request->post('comment','');
            $rate = $this->request->post('rate',0);
            $status = $this->upload();
            if($status==0)$this->error('图片上传失败');
            $orderProduct['thumbs'] = $status['msg'];
            $orderProduct['comment'] = $comment;
            $orderProduct['rate'] = $rate;
            $orderProduct['status'] = '3';
            $orderProduct['comtime'] = time();
            $result = $orderProduct->isUpdate()->save();
            if($result===false)
            {
                $fileList = explode('|',$orderProduct['thumbs']);
                foreach($fileList as $file)
                {
                    @unlink(ROOT_PATH . 'public' . '/' . 'uploads' . $file);
                }
            }
            $this->success('评论成功');
        }
    }
    public function express()
    {
        $orderProductId = $this->request->get('id');
        $orderProduct = OrderProduct::where(['id'=>$orderProductId,'busid'=>$this->business['id']])->find();
        if(!$orderProduct)$this->error('该订单商品不存在');
        if(!$orderProduct['expresscode'])$this->error('该订单商品的物流单号不存在');
        $url = "https://kzexpress.market.alicloudapi.com/api-mall/api/express/query";
        $expressNo = $orderProduct['expresscode'];
        // $expressNo = Random::numeric(14);
        // $expressNo = '320207573310807';
        $params = ['expressNo'=>$expressNo];
        // $params['mobile'] = $this->business['mobile'];
        $headers = [];
        $appcode = '844634427d2440c5b3445dc3b9c1808a';
        array_push($headers, "Authorization:APPCODE " . $appcode);
        array_push($headers, "Content-Type".":"."application/x-www-form-urlencoded; charset=UTF-8");
        $result = Http::post($url,http_build_query($params),[CURLOPT_HTTPHEADER=>$headers]);
        if($result){
            return json_decode($result);
        }else{
            $this->error('查询不到物流信息');
        }
    }
    public function takeover()
    {
        $orderProductId = $this->request->get('orderProductId');
        $orderProduct = OrderProduct::where(['id'=>$orderProductId,'busid'=>$this->business['id']])->find();
        if(!$orderProduct)$this->error('该订单商品不存在');
        if($orderProduct['status']!='1')$this->error('确认收货失败');
        $orderProduct['status'] = '2';
        $result = $orderProduct->isUpdate()->save();
        if($result===false)$this->error('确认收货失败');
        $this->success('确认收货成功');
    }
}